﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;

/*
 * programs, assemblies, namespaces, types, members
 */

/* value types
 * (s)byte, (u)short, (u)int, (u)long, char, float, double, decimal, bool, enum, struct and Nullable.
 * 
 */

/* reference types
 * class, interface, array, delegate
 * 
 */

/* user definable types:
 * class, interface, struct, enum, delegate
 * class, interface, struct, delegate types all supports generics.
 */

namespace SharpExample
{
    class Program
    {
        // constant
        public const double PI = 3.14159265358979323846;
        
        // filed
        private int field1;
 
        // property
        public int Field1
        {
            get { return field1;}
            set { field1 = value; }
        }

        public int Count
        {
            get { return values.Count(); }
        }

        // method
        public int GetCount()
        {
            return values.Count();
        }

        // indexers
        private int [] values;
        public int this[int index]
        {
            get { return values[index]; }
            set 
            { 
                values[index] = value;
                if (OnValueSet != null)
                    OnValueSet(index, value);
            }
        }

        //delegate
        public delegate void Handler(int index, int value);

        //event
        public event Handler OnValueSet;

        //constructor
        public Program()
        {
            values = new int[32];
        }

        //entry point function
        static void Main(string[] args)
        {
            Program p = new Program();

            // subscribe event OnValueSet
            p.OnValueSet += new Handler(p_OnValueSet);
            
            ValueCollection<int> intCollections = new ValueCollection<int>();
            // print all values in p
            for (int i = 0; i < p.Count; ++i) 
            {
                p[i] = i;
                intCollections.Add(i^15);
            }

            Console.WriteLine("print values in intCollections");
            foreach (int val in intCollections)
            {
                Console.Write("{0} ", val);
            }
            Console.WriteLine();
            
            IEnumerable<int> query = from val in intCollections
                                     where (val >= 10 && val <= 30)
                                     select val;

            Console.WriteLine("print values in intCollections that >= 10 and <= 30");
            foreach (int val in query)
            {
                Console.Write("{0} ", val);
            }
            Console.WriteLine();

            IEnumerable<int> filterd_result = intCollections.Where((val) => { return (val >= 10 && val <= 30); });

            foreach (int val in filterd_result)
            {
                Console.Write("{0} ", val);
            }
            Console.WriteLine();
        }

        // event handler
        static void p_OnValueSet(int index, int value)
        {
            Console.WriteLine("set value {0} to array's index {1}", value, index);
        }
    }
}
